// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: declaration of CXFormsElementWithXBLImpl.
//   $Id$



#pragma once

#include "XFormsElement.h"
#include <XBLEngine.h>
#include "XFormsElementDefaultImpl.h"
#include "ElementWithXBL.h"
#include "CComBSTRPtrList.h"

template <class TImpl, class TParse> class CXFormsElementWithXBLImpl
	:public CXFormsElementDefaultImpl<TImpl,TParse,CElementWithXBL,CElementWithXBL>
	,public IDispatchImpl<IEventListener,&IID_IEventListener,&LIBID_DOM2EventsLib,2,0>
{
public:
	CXFormsElementWithXBLImpl(void)
	{
	};
	virtual ~CXFormsElementWithXBLImpl(void)
	{
	};

	BEGIN_COM_MAP(CXFormsElementWithXBLImpl)
		COM_INTERFACE_ENTRY(IEventListener)
		COM_INTERFACE_ENTRY_CHAIN(CXFormsElement)
	END_COM_MAP()

	STDMETHODIMP handleEvent(IDOMEvent * pEvt)
	{
		HRESULT hr = S_FALSE;
		if(pEvt)
		{
			CComBSTR sEventName;
			pEvt->get_type(&sEventName);
			// Remove will this is not a formcontrol
			if(m_pFormControl) {
				if(sEventName == L"fp-valuechanged")
				{
					CComQIPtr<IMutationEvent> pMutation(pEvt);
					if(pMutation)
					{
						CComBSTR sVal = 0;
						pMutation->get_newValue(&sVal);
						// If enabled then update the instance
						// else blank the control as is not relavent
						
						if(m_bEnabled)
							hr = m_pFormControl->putValue(sVal.m_str);
						//else
						//	hr = putDisabledValue();
						// -- removed while developing celementwithvalue object 
					}
				}
				else if(sEventName == "fp-valuechanging")
				{
					BOOL bIncremental = false;
					
					m_pFormControl->getIncremental(&bIncremental);

					if(bIncremental) 
					{
						CComQIPtr<IMutationEvent> pMutation(pEvt);
						if(pMutation)
						{
							CComBSTR sVal;
							pMutation->get_newValue(&sVal);
							hr = m_pFormControl->putValue(sVal.m_str);
						}
					}
				}
				else if(sEventName == L"fp-uiready")
				{
					CImplSingleNodeBinding * p = dynamic_cast<CImplSingleNodeBinding *> (m_pFormControl);
					if(p)
					{
						BSTR sData = 0;
						p->getValue(&sData);
						hr = onfp_putvalue(sData);
						::SysFreeString(sData);
					}
				}
				else
				{
					//Should not normally reach this point.
					::AtlTrace("'formsplayer.dll': unhandled event '%S' occured on control %X",sEventName,this);
				}
			}
		}
		return hr;
	};
	
	virtual HRESULT InitBehaviour()
	{
		HRESULT hr = __super::InitBehaviour();

		return hr;
	};

	virtual HRESULT render()
	{

		populateEvents();
		HRESULT hr = attachEvents();
		return hr;
	};
	virtual HRESULT put_value(BSTR bsValue)
	{
 		HRESULT hr = onfp_putvalue(bsValue);
		return hr;
	};

protected:
			
	virtual HRESULT attachEvents()
	{
		HRESULT hr = S_FALSE;
		CComPtr<IUnknown> pUnk = GetControllingUnknown();
		CComQIPtr<IEventTarget> pThisAsTarget(pUnk);
		CComQIPtr<IEventListener> pThisAsListener(pUnk);
		if(pThisAsTarget)
		{
			CComBSTRPtrList::iterator i = m_lstEvents.begin();
			
			while(i != m_lstEvents.end() && SUCCEEDED(hr))
			{
				hr = pThisAsTarget->addEventListener((*i)->m_str,pThisAsListener,false);
				++i;
			}
		}
		
		return hr;
	};

	virtual HRESULT detachEvents()
	{
		HRESULT hr = S_FALSE;
		CComQIPtr<IEventTarget> pThisAsTarget(GetControllingUnknown());
		CComQIPtr<IEventListener> pThisAsListener(GetControllingUnknown());
		if(pThisAsTarget)
		{
			CComBSTRPtrList::iterator i = m_lstEvents.begin();
			
			while(i != m_lstEvents.end() && SUCCEEDED(hr))
			{
				hr = pThisAsTarget->removeEventListener((*i)->m_str ,pThisAsListener,false);
				++i;
			}
		}
		
		return hr;
	};

private :
	void  populateEvents()
	{
		
		m_lstEvents.push_back(&EVENT_FP_VALUECHANGED);
		m_lstEvents.push_back(&EVENT_FP_VALUECHANGING);
		m_lstEvents.push_back(&EVENT_FP_UIREADY);
	};



	CComBSTRPtrList m_lstEvents;

};


